package com.pubinfo.passbook.api.eip.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.pubinfo.passbook.api.eip.UserInfoService;
import com.pubinfo.passbook.common.entity.TRabbitmqOrgConvert;
import com.pubinfo.passbook.common.entity.TRabbitmqPersonConvert;
import com.pubinfo.passbook.common.entity.TSubsidiaryInfo;
import com.pubinfo.passbook.common.entity.TSystemRole;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.mapper.TRabbitmqOrgConvertMapper;
import com.pubinfo.passbook.common.mapper.TRuleRoleMapper;
import com.pubinfo.passbook.common.mapper.TSubsidiaryInfoMapper;
import com.pubinfo.passbook.common.mapper.TSystemRoleMapper;
import com.pubinfo.passbook.common.model.bo.SubsidiaryDepartment;
import com.pubinfo.passbook.common.model.bo.rabbitmq.TbCert;
import com.pubinfo.passbook.common.model.bo.witeoff.CityInfo;
import com.pubinfo.passbook.common.model.dubbo.ESBServiceData;
import com.pubinfo.passbook.common.model.http.eip.UserInfo;
import com.pubinfo.passbook.common.model.http.eip.UserInformation;
import com.pubinfo.passbook.common.model.vo.system.UserRoleVo;
import com.pubinfo.passbook.common.service.cache.JedisManage;
import com.pubinfo.passbook.common.service.dubbo.DubboService;
import com.pubinfo.passbook.common.service.master.TRabbitmqPersonConvertService;
import com.pubinfo.passbook.common.service.master.TRabbitmqPersonService;
import com.pubinfo.passbook.common.service.master.TSystemRoleService;
import com.pubinfo.passbook.common.utils.HttpUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * EIP登录后用户信息获取
 *
 * @author zhouch
 * @date 2021/12/1 15:47
 */
@Service
public class UserInfoServiceImpl implements UserInfoService {
    private int seconds = 1000 * 60 * 60 * 2;
  @Autowired
  DubboService dubboService;

    @Autowired
    TRabbitmqPersonService personService;

    @Autowired
    TRuleRoleMapper ruleRoleMapper;
    @Resource
    TSystemRoleService roleService;
    @Autowired
    TSystemRoleMapper roleMapper;
    @Autowired
    TSubsidiaryInfoMapper infoMapper;
    @Resource
    JedisManage jedis;
    @Resource
    TRabbitmqOrgConvertMapper convertMapper;
    @Resource
    TRabbitmqPersonConvertService personConvertService;
    final String SUCCESS_RESULT = "OK";

    @Override
    public String userNsrsbhByAcct(String acct) {
        ESBServiceData.CertDetail certDetail = dubboService.getPersonsDetailByIdNo(acct);
        if (certDetail != null) {
            String areaName = certDetail.getSubsidiaryName();
            CityInfo info = infoMapper.findCityInfoByNsrsbh(areaName);
            if (info != null) {
                return info.getNsrsbh();
            }
        }
        return null;
    }
    
    @Override
    public String orgBizNameByAcct(String acct) {
        ESBServiceData.CertDetail certDetail = dubboService.getPersonsDetailByIdNo(acct);
        if (certDetail != null) {
            return certDetail.getAreaName();
        }
        return null;
    }
    
    @Override
    public TSystemRole getCurrentUserRole() {
        List<UserRoleVo> roleList = listCurrentUserRole(getCurrentAcct());
        UserInfo userInfo = getCurrentUserInfo();
        //取第一个
        if (!CollectionUtils.isEmpty(roleList) && userInfo != null && StringUtils.isNotBlank(userInfo.getUserRoleId())) {
            roleList = roleList.stream().filter(role -> role.getUserRoleId().equals(userInfo.getUserRoleId())).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(roleList)) {
            return roleService.lambdaQuery().eq(TSystemRole::getRoleCode, userInfo.getRoleCode()).one();
        }
        return roleList.get(0);
    }
    
    /**
     * 第一次登录时使用UserInfo的jthrLoginName获取角色
     *
     * @return
     */
    @Override
    public UserRoleVo getCurrentUserRoleByNoLogin(String jthrLoginName) {
    
        if (jthrLoginName.indexOf("@") > 0) {
            jthrLoginName = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        }
    
        List<UserRoleVo> roleList = listCurrentUserRole(jthrLoginName);
        //取第一个
        return roleList.get(0);
    }

    @Override
    public List<UserRoleVo> listCurrentUserRole() {
        return listCurrentUserRole(getCurrentAcct());
    }
    
    @Override
    public List<UserRoleVo> listCurrentUserRole(String currentAcct) {
        List<TSubsidiaryInfo> tSubsidiaryInfos = new LambdaQueryChainWrapper<>(infoMapper).eq(TSubsidiaryInfo::getAuditUser, currentAcct).list();
        /**
         * 先查询用户是否为医药费审核员，如果不是，则查询角色表，关联后返回用户角色信息
         * 如果是，则直接返回医药费审核员相关信息
         */
        List<UserRoleVo> roleList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(tSubsidiaryInfos)) {
            roleList = TSystemRole.toList(tSubsidiaryInfos);
        }
        String nsrsbh = userNsrsbhByAcct(currentAcct);
    
        roleList.addAll(roleMapper.listRoleByAcct(currentAcct));
        //查询账号拥有的部门报账员
        List<TRabbitmqOrgConvert> converts = new LambdaQueryChainWrapper<TRabbitmqOrgConvert>(convertMapper).eq(TRabbitmqOrgConvert::getAuditUser, currentAcct).list();
        if (!CollectionUtils.isEmpty(converts)) {
            //根据部门查询公司组织代码
            List<SubsidiaryDepartment> subsidiaryDepartmentList = infoMapper.listByAcctUser(currentAcct);
            
            List<TSystemRole> systemRoleArrayList = new ArrayList<>();
            subsidiaryDepartmentList.stream().map(subsidiaryDepartment -> {
                TSystemRole role = new TSystemRole(subsidiaryDepartment);
                return role;
            }).collect(Collectors.toList());
            roleList.addAll(UserRoleVo.convertRole(systemRoleArrayList));
        }
        if (CollectionUtils.isEmpty(roleList)) {
            List<TSystemRole> userRoleArrayList = new LambdaQueryChainWrapper<TSystemRole>(roleMapper).eq(TSystemRole::getRoleCode, "passbook_user").list();
            roleList.addAll(UserRoleVo.convertRole(userRoleArrayList));
        }
        roleList.forEach(role -> {
            if (StringUtils.isEmpty(role.getNsrsbh())) {
                role.setNsrsbh(nsrsbh);
            }
        });
        roleList.forEach(role -> {
            List<TSystemRole> roles = new LambdaQueryChainWrapper<TSystemRole>(roleMapper).eq(TSystemRole::getRoleCode, role.getRoleCode()).list();
            role.setId(roles.get(0).getId());
            role.setUserRoleId(role.getId() + role.getNsrsbh() + role.getOrgId());
        });
        return roleList;
    }
    
    @Override
    public UserInfo getCurrentUserInfo(String token) {
        String key = USERINFO_CACHE_KEY_PREFIX + token;
        String resultJson = jedis.getStr(key);

        return UserInfo.formStr(resultJson);
    }

    @Override
    public TSystemRole getCurrentUserRole(String nsrsbh) {
        List<UserRoleVo> roleList = listCurrentUserRole(getCurrentAcct());
        //取第一个
        if (!CollectionUtils.isEmpty(roleList)) {
            roleList.stream().filter(role -> role.getNsrsbh().equals(nsrsbh));
        }
        return roleList.get(0);
    }

    @Override
    public String getCurrentUserNsrsbh() {
        String acct = getCurrentAcct();
        ESBServiceData.CertDetail certDetail = dubboService.getPersonsDetailByIdNo(acct);
        if (certDetail != null) {
            String areaName = certDetail.getSubsidiaryName();
            CityInfo info = infoMapper.findCityInfoByNsrsbh(areaName);
            if (info != null) {
                return info.getNsrsbh();
            }
        }
        return null;
    }

    @Override
    public UserInfo getCurrentUserInfo() {
        String token = HttpUtils.getToken(getHttpServletRequest());
        return getCurrentUserInfo(token);
    }

    @Override
    public String getCurrentAcctId() {
        String acct = getCurrentAcct();
        TRabbitmqPersonConvert rabbitmqPerson = personConvertService.getPersonByAcct(acct);
        if (rabbitmqPerson != null) {
            return String.valueOf(rabbitmqPerson.getAcctId());
        }
        return null;
    }

    @Override
    public String getCurrentAcct() {
        UserInfo userInfo = getCurrentUserInfo();
        if (userInfo != null) {
            String jthrLoginName = userInfo.getJthrLoginName();
            String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
            return acct;
        }
        return null;
    }

    @Override
    public TRabbitmqPersonConvert getCurrent4AUserInfo(String token) {

        return personConvertService.getPersonByAcct(getCurrentAcct());
    }

    @Override
    public Boolean judgeRole(String roleCode) {
        UserInfo userInfo = getCurrentUserInfo();
        String jthrLoginName = userInfo.getJthrLoginName();
        String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        List<TSystemRole> roles = ruleRoleMapper.findRolesByAcct(acct, roleCode);
        return !CollectionUtils.isEmpty(roles);
    }
    
    @Override
    public TSystemRole getRoleInfo() {

//        UserInfo userInfo = getCurrentUserInfo();
//        String jthrLoginName = userInfo.getJthrLoginName();
//        String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        return getCurrentUserRole();
    }
    
    @Override
    public TSystemRole getContractRoleInfo() {
        
        return null;
    }
    
    @Override
    public Boolean setCurrentUserInfo(String token, UserInfo user) {
        String key = USERINFO_CACHE_KEY_PREFIX + token;
        
        // 设置用户真实姓名, EIP 可能不存在该字段
        user.setRealname(getPersonCertByAcct(user).getCertName());
  
      String result = jedis.putStr(key, seconds, user.toString());
        
        return result.contentEquals(SUCCESS_RESULT);
    
    }
    
    @Override
    public Boolean setNsrsbhToCurrentUserInfo(String roleId, String nsrsbh, String orgId) {
        String key = USERINFO_CACHE_KEY_PREFIX + HttpUtils.getToken(getHttpServletRequest());
        UserInfo info = getCurrentUserInfo();
        TSystemRole role = roleService.getById(roleId);
        //   if(role.getRoleCode().indexOf("passbook")!=-1){
        info.setNsrsbh(nsrsbh);
        //   }
        if (role != null) {
            info.setRoleCode(role.getRoleCode());
        }
        if (StringUtils.isNotBlank(orgId) && !"null".contentEquals(orgId)) {
            info.setOrgId(Long.valueOf(orgId));
        } else {
            info.setOrgId(null);
        }
    
        info.setUserRoleId(String.format(roleId, nsrsbh, orgId));
  
      String result = jedis.putStr(key, seconds, info.toString());
        return result.contentEquals(SUCCESS_RESULT);
    }
    
    @Override
    public Boolean setNsrsbhToCurrentUserInfo(String roleId) {
        String key = USERINFO_CACHE_KEY_PREFIX + HttpUtils.getToken(getHttpServletRequest());
        
        UserInfo info = getCurrentUserInfo();
      TSystemRole role = roleService.getById(roleId);
      String result = jedis.putStr(key, seconds, info.toString());
        
        return result.contentEquals(SUCCESS_RESULT);
    }
    
    @Override
    public UserInformation getUserInformation() {
        String token = HttpUtils.getToken(getHttpServletRequest());
        return new UserInformation(getCurrentUserInfo(), token, TSystemRole.convertVo(listCurrentUserRole()));
    }
    
    /**
     * 通过userinfo的acct获得用户身份信息
     * (EIP方的真实姓名存在数据错误，所以真实姓名从4A处获取)
     *
     * @param info
     * @return
     */
    public TbCert getPersonCertByAcct(UserInfo info) {
        TRabbitmqPersonConvert person = get4APersonByUserInfo(info);
        try {
            return person.getTbCert().get(0);

        } catch (NullPointerException exp) {
            throw new ServiceException("获取用户身份信息数据失败从tb_cert字段，请检查该数据是否为脏数据. acct = " + person.getAcct());
        }
    }

    public HttpServletRequest getHttpServletRequest() {
        //获取request、response、session
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return requestAttributes.getRequest();
        }
        return null;
    }

    public TRabbitmqPersonConvert get4APersonByUserInfo(UserInfo info) {
        String acct = info.getJthrLoginName().substring(0, info.getJthrLoginName().indexOf("@"));
        TRabbitmqPersonConvert person = new LambdaQueryChainWrapper<>(personConvertService.getBaseMapper())
                .eq(TRabbitmqPersonConvert::getAcct, acct)
                .one();
        if (person == null) {
            throw new ServiceException("不存在该用户");
        }
        return person;
    }
}
